package connect3.team7.util;

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

import java.util.*;
import java.io.Serializable;

import connect3.team7.game.*;
import connect3.team7.gui.*;

public class ClientController implements Client, Serializable {
    
  private static final long serialVersionUID = 231L;

  // client-side variables
  private static ClientController instance;
  private Client stub;
  private String bind_name;
  private Client clientRemoteObj;
  private Registry clientRegistry;
  
  // server-side variables
  private String host_lookup;
  private Registry hostRegistry;
  private Host hostRemoteObj;

  /*
  private ClientController(ClientConnectionSettings ccs) {
    super();
    bind_name   = "ClientController";
    host_lookup = "HostController";
    
    try {
      UnicastRemoteObject.exportObject(this);
    } catch (RemoteException ex) {
        ex.printStackTrace();
    }
  }
   */
  
  public ClientController() {
      super();
      host_lookup = "HostController";
      
      try {
        stub = (Client) UnicastRemoteObject.exportObject(this,0);
      } catch (RemoteException ex) {
        ex.printStackTrace();
      } 
  }

  /*
  public static ClientController getInstance(ClientConnectionSettings ccs) {
    if (instance == null)
      instance = new ClientController(ccs);

    return instance;
  }
   */
  
  public static ClientController getInstance() {
      if (instance == null)
          instance = new ClientController();
      
      return instance;
  }

  public void retrieveRemoteHost(HostConnectionSettings host) {
    try {
      hostRegistry = LocateRegistry.getRegistry(host.getIP(), host.getPort());
      hostRemoteObj = (Host) hostRegistry.lookup(host_lookup);
    } catch(Exception e) {
      System.err.println("ClientController exception: ");
      e.printStackTrace(); 
    }
  }

  /*
  private void registerClientRMI(ClientConnectionSettings ccs) {
    try {
      System.setProperty("java.rmi.server.hostname", ccs.ip);
      System.setProperty("java.rmi.server.codebase", ConfigProperties.getConfigProperties().getProperty("rmi.codebase")); 
  
      clientRegistry = LocateRegistry.createRegistry(ccs.port);
      
      stub = (Client) UnicastRemoteObject.exportObject(this, ccs.port);
  
      clientRegistry.rebind(bind_name, stub);
      System.out.println("ClientController registered");
    } catch (Exception e) {
      System.out.println("ClientController exception");
      e.printStackTrace();
    }
  }

   */
  
  public static ArrayList<HostConnectionSettings> getAvailableHosts() {
    DBController db = DBController.getInstance();
    ArrayList<HostConnectionSettings> host_lst = db.getHostListing(); 

    return host_lst;
  }

  public boolean join(Player p) throws RemoteException {
    boolean ret = hostRemoteObj.join(p, stub);

    if (ret) {
      System.out.println("joined game!");
      return ret;
    } else {
      System.out.println("booted!");
      return ret;
    }
  }
  
  public Enumeration<String> getActivePlayers() {
      Enumeration<String> e = null;
      
      try {
          e = hostRemoteObj.getActivePlayers();
      } catch (RemoteException ex) {
          ex.printStackTrace();
      }
      
      return e;  
  }
  
  

  public void sendMoveToHost(Token t) throws RemoteException {
    hostRemoteObj.receiveClientMove(t);
  }

  public synchronized void syncGameBoardFromHost(Token t) {
    System.out.println("Broadcast move (" + t.getX() + "," + t.getY() + ") received from host!");  
  }
  
  public synchronized void updateActivePlayers(String s) {
      Connect3View c3v = Connect3View.getInstance();
      //c3v.updateActivePlayersList(s);
  }
}
